import axios from 'axios'
import $store from '@/store/index'
import http from './http'
const CACHE_EXPIRE_TIME=parseInt(import.meta.env.VITE_PAGE_CACHE_EXPIRE);
const RETRY_COUNT=parseInt(import.meta.env.VITE_HTTP_RETRY_COUNT)
const RETRY_DELAY=parseInt(import.meta.env.VITE_HTTP_RETRY_DELAY)
const succCode=[200,0];
const CancelToken = axios.CancelToken;
//生成请求唯一key
function getReqKey(config){
  if(!config) return
  let params=config.params,data=config.data;
  if(params&&typeof params=='object'){
    params=JSON.stringify(params)
  }
  if(data&&typeof data=='object'){
    data=JSON.stringify(data)
  }
  return `${config.method}:${config.baseURL}${config.url}:${params}:${data}`;
}
//取消重复请求
class HttpPending{
  readonly pendingMap=new Map()
  addPending(config){
    if(!config) return
    const key=getReqKey(config)
    if(!this.pendingMap.has(key)){
      this.pendingMap.set(key,config._cancel)
    }else{
      config._cancel({
        msg:`Repeat request:${key}`,
        _config:config,
      });
    }
  }
  removePending(config){
    if(!config) return
    const key=getReqKey(config)
    if(this.pendingMap.has(key)){
      this.pendingMap.delete(key);
    }
  }
  clear(){
    this.pendingMap.clear()
  }
}
//缓存请求数据
class HttpCache{
  readonly cacheMap=new Map();
  readonly STORAGE_KEY='HTTP_CACHE_MAP'
  constructor(){
    const cache=localStorage.getItem(this.STORAGE_KEY)
    if(cache){
      const obj:Object=JSON.parse(cache)
      this.cacheMap=new Map(Object.entries(obj))
    }
    window.addEventListener("unload", (e) =>{
      localStorage.setItem(this.STORAGE_KEY,JSON.stringify(Object.fromEntries(this.cacheMap)))
    })
  }
  addCache(response){
    if(!response) return
    const key=getReqKey(response.config)
    const time=(new Date()).getTime();
    if(response.config.cache&&succCode.includes(response.data.code)&&!this.cacheMap.has(key)){
      response.data._cache=true
      this.cacheMap.set(key,{
        data:response.data,
        time:time,
        expire:response.config.cacheExpire??CACHE_EXPIRE_TIME
      })
    }
  }
  checkCache(config){
    if(!config) return
    const key=getReqKey(config)
    const time=(new Date()).getTime();
    if(config.cache&&this.cacheMap.has(key)){
      const cache=this.cacheMap.get(key)
      if(time-cache.time<(config.cacheExpire??CACHE_EXPIRE_TIME)){
        config._cancel({
          msg:`Cached request:${key}`,
          data:cache.data,
          _config:config,
          _cache:true,
          _time:cache.time
        })
      }else{
        this.cacheMap.delete(key)
      }
    }
  }
  clear(){
    this.cacheMap.clear()
    localStorage.removeItem(this.STORAGE_KEY)
  }
}

//添加取消请求功能
function addReqCancel(config){
  if(!config) return
  const source = CancelToken.source()
  config.cancelToken=source.token
  config._cancel=source.cancel
}
//检查token
function checkReqAuth(config){
  if(!config) return
  const key=getReqKey(config)
  const token=$store.getters['user/getToken'];
  if(token){
    config.headers['x-token']=token;
  }
  if(config.reqAuth&&!token){
    config._cancel({
      msg:`Auth request:${key}`
    });
  }
}
//请求失败重连
async function httpRetry(config){
  if(!config) return
  config._retryCount??=0
  if(config._retryCount>=RETRY_COUNT) return
  return new Promise((resolve,reject) =>{
    setTimeout(() => {
      config._retryCount++
      http(config).then(res =>{
        resolve(res)
      }).catch(err =>{
        reject(err)
      })
    },RETRY_DELAY);
  })
}
export {
  HttpPending,HttpCache,getReqKey,addReqCancel,checkReqAuth,httpRetry
}